package com.rk.section1;

import java.util.Map;
import java.util.stream.Collectors;

public class StatementDataCreator {

    public StatementData createStatementData(Invoice invoice, Map<String, Play> plays) {
        StatementData data = new StatementData();
        data.setCustomer(invoice.getCustomer());
        data.setPerformances(invoice.getPerformances().stream()
                .map(performance -> enrichPerformance(plays, performance))
                .collect(Collectors.toList()));
        data.setTotalAmount(totalAmount(data));
        data.setTotalVolumeCredits(totalVolumeCredits(data));
        return data;
    }

    private Performance enrichPerformance(Map<String, Play> plays, Performance performance) {
        PerformanceCalculator performanceCalculator = createPerformanceCalculator(plays, performance);
        performance.setPlay(performanceCalculator.getPlay());
        performance.setAmount(performanceCalculator.amountFor());
        performance.setVolumeCredits(performanceCalculator.volumeCreditsFor());
        return performance;
    }

    private PerformanceCalculator createPerformanceCalculator(Map<String, Play> plays, Performance performance) {
        Play play = playFor(plays, performance);
        switch (play.getType()) {
            case "tragedy":
                return new TragedyCalculator(performance, play);
            case "comedy":
                return new ComedyCalculator(performance, play);
            default:
                throw new Error("unknown type：" + performance.getPlay().getType());
        }
    }

    private int totalAmount(StatementData data) {
        return data.getPerformances().stream().mapToInt(Performance::getAmount).sum();
    }

    private int totalVolumeCredits(StatementData data) {
        return data.getPerformances().stream().mapToInt(Performance::getVolumeCredits).sum();
    }

    private Play playFor(Map<String, Play> plays, Performance performance) {
        return plays.get(performance.getPlayID());
    }

}
